#include "../lib_include/EventLoopThreadPool.h"
#include "../lib_include/EventLoop.h"
#include "../lib_include/EventLoopThread.h"

#include <stdio.h>

using namespace netlib;
using namespace netlib::net;

EventLoopThreadPool::EventLoopThreadPool(EventLoop* baseLoop, const string& nameArg)
  : baseLoop_(baseLoop),
    name_(nameArg),
    started_(false),
    numThreads_(0),
    next_(0)
{ }

EventLoopThreadPool::~EventLoopThreadPool()
{ }

void EventLoopThreadPool::start(const ThreadInitCallback& cb) // 开启线程池
{
    assert(!started_);
    baseLoop_->assertInLoopThread(); // 断言在主IO线程中

    started_ = true;

    for (int i = 0; i < numThreads_; ++i) // 循环创建线程
    {
        char buf[name_.size() + 32];
        snprintf(buf, sizeof buf, "%s%d", name_.c_str(), i);
        EventLoopThread* t = new EventLoopThread(cb, buf);
        threads_.push_back(std::unique_ptr<EventLoopThread>(t));

        // 调用t->startLoop()开启线程，开启事件循环之前调用cb()
        loops_.push_back(t->startLoop());
    }
    if (numThreads_ == 0 && cb)
        cb(baseLoop_);
}

// 轮叫方式，为新连接分派一个IO线程
EventLoop* EventLoopThreadPool::getNextLoop()
{
    baseLoop_->assertInLoopThread();
    assert(started_);
    EventLoop* loop = baseLoop_; // 获得主IO线程

    if (!loops_.empty()) // 如果IO线程池不为空
    {
        // loops_不为空，按照round-robin（RB-轮叫）的调度方式选择一个EventLoop对象
        loop = loops_[next_];
        ++next_;
        if (implicit_cast<size_t>(next_) >= loops_.size()) // 循环到末尾时，置零开始
            next_ = 0;
    }
    return loop; // 如果loops_为空，则返回主IO线程
}

// 哈希算法方式，为新连接分派一个IO线程
EventLoop* EventLoopThreadPool::getLoopForHash(size_t hashCode)
{
    baseLoop_->assertInLoopThread();
    EventLoop* loop = baseLoop_;

    if (!loops_.empty())
        loop = loops_[hashCode % loops_.size()];
    return loop;
}

// 返回EventLoop列表loops_，如果loops_为空则返回主IO线程
std::vector<EventLoop*> EventLoopThreadPool::getAllLoops()
{
    baseLoop_->assertInLoopThread();
    assert(started_);
    if (loops_.empty())
        return std::vector<EventLoop*>(1, baseLoop_);
    else
        return loops_;
}
